package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * java 反射机制
 * 
 * 反射机制是一种动态机制，允许我们程序在运行期间确定实例化对象的操作，方法调用的操作和
 * 属性赋值等操作。
 * 
 * 反射可以大大提高代码灵活度，但是也会带来更多的系统开销和降低运行性能。因此反射只在关
 * 键地方使用而不能过度依赖。
 * @author pc
 *
 */
public class ReflectDemo1 {
	public static void main(String[] args) throws ClassNotFoundException {
		/*
		 * Class类 称为:类的类对象
		 * 该类的每一个实例用于表示已经被JVM加载的一个类，并且每个被JVM加载的类都有
		 * 且只有一个类对象与之关联。
		 * 通过类对象我们可以得知其表示的类的一切信息:类名，有哪些属性，方法，构造器
		 * 并可以获取它们以便在运行期间调用。
		 * 
		 * 所以反射的第一步就是获取要操作的类的类对象。
		 * 
		 * 获取一个类的类对象有三种方式:
		 * 1:类名.class
		 *   例如:String.class
		 *   	  ArrayList.class
		 *   
		 * 2:Class.forName(String className)  
		 *   Class提供了一个静态方法forName，可以根据类的完全限定名(包名.类名)形式
		 *   获取该类的类对象
		 * 
		 * 3:ClassLoader类加载器形式  
		 */
		
		//获取String的类对象
//		Class cls = String.class;//优点是简单直接，但是缺点是硬编码获取
		/*
		 * 该方法会抛出ClassNotFoundException,当给定的类的完全限定名无效时会抛出
		 * 该异常。
		 */
//		Class<?> cls = Class.forName("java.lang.String");
//		Class<?> cls = Class.forName("reflect.Person");
		/*
		 * java.lang.String
		 * java.util.ArrayList
		 * java.util.HashSet
		 * java.util.HashMap
		 * java.io.FileOutputStream
		 * reflect.Person
		 * 以上可參考
		 */
		System.out.println("请输入一个类名:");
		Scanner scanner = new Scanner(System.in);
		String className = scanner.nextLine();		
		Class<?> cls = Class.forName(className);
		
		//获取类名
		String name = cls.getName();
		System.out.println(name);
		/*
		 * Method类的每一个实例用于表示某个类中的某个方法
		 * 
		 * Class提供的方法:
		 * Method[] getMethods()
		 * 可以获取Class表示的类的所有公有方法
		 */
		System.out.println("获取本类所有公有方法，包含从超类继承的方法");
		Method[] methods= cls.getMethods();
		for(Method m : methods) {
			System.out.println(m.getName());
		}
		
		
		System.out.println("获取本类定义的所有方法(不含有继承的方法):");
		methods = cls.getDeclaredMethods();
		for(Method m : methods) {
			System.out.println(m.getName());
		}
	}
}
















